package cate.game.activity.hangdrop;

import cate.common.table.activity.hangdrop.common.HangDropActivityCommonRow;
import cate.common.table.d.GDFunc;
import cate.common.table.d.GDObj;
import cate.common.table.d.GDOperation;
import cate.common.table.pay.PayItemRow;
import cate.common.util.GameResult;
import cp.solution.business.game.component.NoticeParam;
import cate.game.activity.base.core.RoleActivitySingle;
import cate.game.activity.hangdrop.msg.HangDropActivityInfoResp;
import cate.game.activity.hangdrop.po.HangDropExchangePO;
import cate.game.activity.hangdrop.po.HangDropShopPO;
import cate.game.mail.po.MailBuilder;
import cate.game.res.MixRes;
import cate.game.res.MixResItem;
import cate.game.role.Role;
import cate.game.role.mail.Mail;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;


@NoteClass("限时兑换活动")
public class HangDropActivity extends RoleActivitySingle {
    @NoteField("是否结束掉落")
    public boolean dropStopped;
    @NoteField("当前兑换材料数量")
    public long materialsNum;
    @NoteField("计算挂机的剩余分钟")
    public int minutesLeft;
    @NoteField("兑换数据")
    public HangDropExchangePO exchangePO;
    @NoteField("限购礼包")
    public HangDropShopPO shopPO;

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (exchangePO == null) {
            exchangePO = new HangDropExchangePO();
        }
        exchangePO.initialize(this);
        if (shopPO == null) {
            shopPO = new HangDropShopPO();
        }
        shopPO.initialize(this);
    }

    @Override
    public void onEnter() {
        super.onEnter();
        checkDropStopped(true);
    }

    @Override
    public void excelCheck() {
        exchangePO.excelCheck();
        shopPO.excelCheck();
    }

    public void clear() {
        dropStopped = false;
        materialsNum = 0;
        minutesLeft = 0;
        exchangePO.clear();
        shopPO.clear();
    }

    public void noticeUpdate() {
        role.sendNow(new HangDropActivityInfoResp(this));
    }

    @Override
    public void onDaySpan(boolean silence) {
        super.onDaySpan(silence);
        checkDropStopped(silence);
        shopPO.onDaySpan(silence);
        if (!silence) {
            noticeUpdate();
        }
    }

    @Override
    public void onRoleOpen() {

    }

    @Override
    public void onRoleEnd() {
        HangDropActivityCommonRow config = getCommonConfig();
        if (config != null && config.endMailId != 0) {
            MailBuilder builder = new MailBuilder()
                    .setContentId(config.endMailId);
            if (config.nameLangId == -1) {
                builder.setNoticeParamList(new NoticeParam(NoticeParam.NoticeType.STRING, config.name));
            } else {
                builder.setNoticeParamList(new NoticeParam(NoticeParam.NoticeType.TRANSLATE_STRING, config.nameLangId));
            }
            if (materialsNum > 0 && config.overdueGoldRatio > 0) {
                MixRes endRes = new MixRes();
                endRes.addItem(new MixResItem(GDObj.Type.NUM, GDObj.Num.M0, materialsNum * config.overdueGoldRatio));
                builder.setReward(endRes);
            }
            Mail endMail = builder.build();
            role.getGame().mail.send(role, endMail);
        }
        // 防止接口重入
        materialsNum = 0;
        role.getFarm().adventure.removeOnHangDropActivityOver(funcId());
        clear();
    }

    @Override
    public void initSend() {
        noticeUpdate();
    }

    /**
     * 检测是否结束掉落
     *
     * @param silence 是否消息静默
     */
    private void checkDropStopped(boolean silence) {
        HangDropActivityCommonRow config = getCommonConfig();
        if (config == null) {
            return;
        }
        int day = getCurrentDay();
        if (!dropStopped) {
            if (day > config.dropDay) {
                setDropStop(silence);
            }
        } else {
            if (day <= config.dropDay) {
                dropStopped = false;
            }
        }
    }

    /**
     * 设置掉落结束
     */
    private void setDropStop(boolean silence) {
        dropStopped = true;
        HangDropActivityCommonRow config = getCommonConfig();
        if (config != null && config.warnMailId != 0) {
            MailBuilder builder = new MailBuilder()
                    .setContentId(config.warnMailId);
            if (config.nameLangId == -1) {
                builder.setNoticeParamList(new NoticeParam(NoticeParam.NoticeType.STRING, config.name));
            } else {
                builder.setNoticeParamList(new NoticeParam(NoticeParam.NoticeType.TRANSLATE_STRING, config.nameLangId));
            }
            Mail warnMail = builder.build();
            role.getGame().mail.send(role, warnMail);
        }
        if (!silence) {
            noticeUpdate();
        }
    }

    /**
     * 获取基础配置
     */
    @JsonIgnore
    public HangDropActivityCommonRow getCommonConfig() {
        switch (funcId()) {
            case GDFunc.ACT_HANG_DROP:
            case GDFunc.HANG_DROP_HERO_EXCHANGE:
            case GDFunc.HANG_DROP_SPICE_UP:
            case GDFunc.HANG_DROP_WISH_BLESSING:
            case GDFunc.HANG_DROP_CROSS_DIAMOND:
            case GDFunc.HANG_DROP_CROSS_GOD_EQUIP:
                return role.getGame().table.hangDropActivity.common.get(configTid());
            default:
                return null;
        }
    }

    /**
     * 获取当前分组
     */
    @JsonIgnore
    public int getGroup() {
        HangDropActivityCommonRow config = getCommonConfig();
        return config == null ? 0 : config.group;
    }

    /**
     * 获取操作代号
     */
    @JsonIgnore
    public int getGDOperation() {
        switch (funcId()) {
            case GDFunc.ACT_HANG_DROP:
                return GDOperation.ACT_HANG_DROP;
            case GDFunc.HANG_DROP_HERO_EXCHANGE:
                return GDOperation.HANG_DROP_HERO_EXCHANGE;
            case GDFunc.HANG_DROP_SPICE_UP:
                return GDOperation.HANG_DROP_SPICE_UP;
            case GDFunc.HANG_DROP_WISH_BLESSING:
                return GDOperation.HANG_DROP_WISH_BLESSING;
            case GDFunc.HANG_DROP_CROSS_DIAMOND:
                return GDOperation.HANG_DROP_CROSS_DIAMOND;
            case GDFunc.HANG_DROP_CROSS_GOD_EQUIP:
                return GDOperation.HANG_DROP_CROSS_GOD_EQUIP;
            default:
                return GDOperation.NULL;
        }
    }

    @Override
    public GameResult<Void> allowPay(PayItemRow payItemRow) {
        if (dropStopped) {
            return new GameResult<Void>().fail("购买期已结束");
        }
        return shopPO.allowBuy(payItemRow.funcSubId);
    }

    @Override
    public void onPaySuccess(PayItemRow payItemRow) {
        shopPO.supplyGifts(payItemRow.funcSubId, 1);
    }

    /**
     * 计算掉落
     */
    public MixRes calcHangDrop(int minutes) {
        if (dropStopped) {
            return null;
        }
        HangDropActivityCommonRow config = getCommonConfig();
        if (config == null || config.dropInterval == 0) {
            return null;
        }
        int exact_minutes = minutesLeft + minutes;
        int round = exact_minutes / config.dropInterval;
        minutesLeft = exact_minutes % config.dropInterval;
        if (round <= 0) {
            return null;
        }
        int totalNum = 0;
        for (int i = 0; i < round; i++) {
            int num = config.getNum();
            if (num > 0) {
                totalNum += num;
            }
        }
        if (totalNum <= 0) {
            return null;
        }
        MixRes res = new MixRes();
        res.addItem(new MixResItem(GDObj.Type.PROP, config.dropItemId, totalNum));
        return res;
    }

    /**
     * 添加材料数量
     */
    public void addMaterialsNum(int materialsId, long num) {
        HangDropActivityCommonRow config = getCommonConfig();
        if (config == null || config.dropItemId != materialsId) {
            return;
        }
        changeMaterialsNum(num, false);
    }

    /**
     * 改变材料数量
     */
    public EcResult<Void> changeMaterialsNum(long num, boolean silence) {
        EcResult<Void> r = new EcResult<>();
        if (num < 0 && materialsNum + num < 0) {
            return r.fail("材料数量不足");
        }
        materialsNum += num;
        if (!silence) {
            noticeUpdate();
        }
        return r.success();
    }

    /**
     * 处理兑换
     *
     * @param tid 配置ID
     * @param num 兑换数量
     * @return 兑换结果 携带活动数据本身
     */
    public EcResult<HangDropActivity> doExchange(int tid, int num) {
        EcResult<HangDropActivity> r = new EcResult<>();
        r.data = this;
        EcResult<Void> r_exchange = exchangePO.doExchange(tid, num);
        if (!r_exchange.ok()) {
            return r.fail(r_exchange.message);
        }
        return r.success();
    }

    /**
     * 处理购买礼包
     *
     * @param tid 配置ID
     * @param num 购买数量
     * @return 购买结果 携带活动数据本身
     */
    public EcResult<HangDropActivity> doBuyGift(int tid, int num) {
        EcResult<HangDropActivity> r = new EcResult<>();
        r.data = this;
        if (dropStopped) {
            return r.fail("已超出购买时间!");
        }
        EcResult<Void> r_buy = shopPO.doBuyGift(tid, num);
        if (!r_buy.ok()) {
            return r.fail(r_buy.message);
        }
        return r.success();
    }

    /**
     * GM设置结束掉落
     */
    public void GMSetDropStopped() {
        if (!dropStopped) {
            setDropStop(false);
        } else {
            dropStopped = false;
        }
    }
}
